home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / AmiVoGL_MDEV.lha / src / clip.c < prev    next >
C/C++ Source or Header  |  1994-04-12  |  3KB  |  153 lines

  1. #include "vogl.h"
  2.  
  3. static int planes[] = {'\01', '\02', '\04', '\010', '\020', '\040'};
  4.  
  5. float wc[2][6];
  6.  
  7. /*
  8.  * clip
  9.  *
  10.  * Clips a 3D line using Homogeneous clipping.
  11.  * Reference: Newman and Sproull
  12.  *
  13.  */
  14. void clip(
  15.   register Vector p0,
  16.   register Vector p1)
  17. {
  18. float    t, t1, t2, dx, dy, dz, dw;
  19. int    vx, vy, c1, c2, i;
  20.  
  21. c1 = MakeEdgeCoords(0, p0);
  22. c2 = MakeEdgeCoords(1, p1);
  23.  
  24. if (!(c1 & c2)) {
  25.  
  26.     t1 = 0.0;
  27.     t2 = 1.0;
  28.     for (i = 0; i < 6; i++)
  29.     if (wc[0][i] < 0.0 || wc[1][i] < 0.0) {
  30.         t = wc[0][i] / (wc[0][i] - wc[1][i]);
  31.         if (wc[0][i] < 0.0) {
  32.             if (t > t1) 
  33.                 t1 = t;
  34.             }
  35.         else if (t < t2) 
  36.             t2 = t;
  37.         }
  38.      
  39.      if (t2 >= t1) {
  40.         vdevice.cpVvalid = 1;
  41.         dx = p1[V_X] - p0[V_X];
  42.         dy = p1[V_Y] - p0[V_Y];
  43.         dz = p1[V_Z] - p0[V_Z];
  44.         dw = p1[V_W] - p0[V_W];
  45.         if (t2 != 1.0) {
  46.             p1[V_X] = p0[V_X] + t2 * dx;
  47.             p1[V_Y] = p0[V_Y] + t2 * dy;
  48.             p1[V_Z] = p0[V_Z] + t2 * dz;
  49.             p1[V_W] = p0[V_W] + t2 * dw;
  50.             vdevice.cpVvalid = 0;
  51.             }
  52.         if (t1 != 0.0) {
  53.             p0[V_X] = p0[V_X] + t1 * dx;
  54.             p0[V_Y] = p0[V_Y] + t1 * dy;
  55.             p0[V_Z] = p0[V_Z] + t1 * dz;
  56.             p0[V_W] = p0[V_W] + t1 * dw;
  57.             }
  58.         vdevice.cpVx = WtoVx(p0);
  59.         vdevice.cpVy = WtoVy(p0);
  60.         vx = WtoVx(p1);
  61.         vy = WtoVy(p1);
  62.         (*vdevice.dev.Vdraw)(vx, vy);
  63.         vdevice.cpVx = vx;
  64.         vdevice.cpVy = vy;
  65.         }
  66.     }
  67. }
  68.  
  69. /* ------------------------------------------------------------------------ */
  70.  
  71. /*
  72.  * MakeEdgeCoords
  73.  *
  74.  * calculates distance from point to each clipping plane in Homogeneous
  75.  * clipping coordinates. Return code if on outside of any clipping plane
  76.  *
  77.  */
  78. int MakeEdgeCoords(
  79.   int i,
  80.   Vector p)
  81. {
  82. int    j, k = 0;
  83.  
  84. wc[i][0] = p[V_W] + p[V_X];
  85. wc[i][1] = p[V_W] - p[V_X];
  86. wc[i][2] = p[V_W] + p[V_Y];
  87. wc[i][3] = p[V_W] - p[V_Y];
  88. wc[i][4] = p[V_W] + p[V_Z];
  89. wc[i][5] = p[V_W] - p[V_Z];
  90.  
  91. for (j = 0; j < 6; j++)
  92. if (wc[i][j] < 0.0)
  93. k |= planes[j];
  94.  
  95. return(k);
  96. }
  97.  
  98. /* ------------------------------------------------------------------------ */
  99.  
  100. /*
  101.  * quickclip
  102.  *
  103.  * A variation on the above that assumes p0 is a valid position in device coords
  104.  *
  105.  */
  106. void quickclip(
  107.   register Vector p0,
  108.   register Vector p1)
  109. {
  110. register float    t, t1;
  111. register int    vx, vy, i;
  112.  
  113. t1 = 1.0;
  114.  
  115. wc[0][0] = p0[V_W] + p0[V_X];
  116. wc[0][1] = p0[V_W] - p0[V_X];
  117. wc[0][2] = p0[V_W] + p0[V_Y];
  118. wc[0][3] = p0[V_W] - p0[V_Y];
  119. wc[0][4] = p0[V_W] + p0[V_Z];
  120. wc[0][5] = p0[V_W] - p0[V_Z];
  121. wc[1][0] = p1[V_W] + p1[V_X];
  122. wc[1][1] = p1[V_W] - p1[V_X];
  123. wc[1][2] = p1[V_W] + p1[V_Y];
  124. wc[1][3] = p1[V_W] - p1[V_Y];
  125. wc[1][4] = p1[V_W] + p1[V_Z];
  126. wc[1][5] = p1[V_W] - p1[V_Z];
  127.  
  128. for (i = 0; i < 6; i++)
  129. if (wc[0][i] >= 0.0 && wc[1][i] < 0.0) {
  130.     t = wc[0][i] / (wc[0][i] - wc[1][i]);
  131.     if (t < t1)
  132.         t1 = t;
  133.     }
  134.  
  135. vdevice.cpVvalid = 1;
  136. if (t1 != 1.0) {
  137.     p1[V_X] = p0[V_X] + t1 * (p1[V_X] - p0[V_X]);
  138.     p1[V_Y] = p0[V_Y] + t1 * (p1[V_Y] - p0[V_Y]);
  139.     p1[V_Z] = p0[V_Z] + t1 * (p1[V_Z] - p0[V_Z]);
  140.     p1[V_W] = p0[V_W] + t1 * (p1[V_W] - p0[V_W]);
  141.     vdevice.cpVvalid = 0;
  142.     }
  143.  
  144. vx = WtoVx(p1);
  145. vy = WtoVy(p1);
  146. (*vdevice.dev.Vdraw)(vx, vy);
  147. vdevice.cpVx = vx;
  148. vdevice.cpVy = vy;
  149. }
  150.  
  151. /* ------------------------------------------------------------------------ */
  152.  
  153.